#include "Kernel.fh"
#include "Multiboot.fh"

#if 1
#define MULTIBOOT_TRACE(x ...)	TRACE("Multiboot: " x)
#else
#define MULTIBOOT_TRACE(x ...)
#endif

KernelArgs_t * Multiboot_PrepareArgs( MultibootInfo_t * info )
{
	if( info == NULL )
		return NULL;

	MULTIBOOT_TRACE( "Info Received... %p\n", info );
	MULTIBOOT_TRACE( "Memory: Lower=%u, Upper=%u\n", info->fMemory.fLower * 1024, info->fMemory.fUpper * 1024 );

	static KernelArgs_t args;
	Memory_Set( &args, 0, sizeof(KernelArgs_t) );

	args.fMemory.fLower = info->fMemory.fLower;
	args.fMemory.fUpper = info->fMemory.fUpper;

	args.fCommandLine = (char *)info->fCommandLine;

	args.fModules.fCount = info->fModules.fCount;
	args.fModules.fFirst = (Kernel_Module *)info->fModules.fBaseAddress;

	MultibootModule_t * mbModule = (MultibootModule_t *)info->fModules.ffBaseAddress;
	KernelModule_t * kModule = (KernelModule_t *)info->fModules.ffBaseAddress;

	MULTIBOOT_TRACE( "Modules: %i\n", info->fModules.fCount );

	KernelModule_t * kLastModule = NULL;
	for( uint32 i = 0; i < info->fModules.fCount; i++ )
	{
		if( kLastModule != NULL )
			kLastModule->fNext = kModule;

		uint32 start = mbModule->fBaseAddress;
		uint32 length = mbModule->fEndAddress -  mbModule->fBaseAddress;
		char * identifier = (char *)mbModule->fString;

		MULTIBOOT_TRACE( "\tStart=%08x, Length=%08x, Identifier=%s\n", start, length, identifier );

		kModule->fIdentifier = identifier;
		kModule->fData = (void *)start;
		kModule->fLength = length;
		kModule->fNext = NULL;

		kLastModule = kModule;

		mbModule = (MultibootModule_t *)( (Address)mbModule + sizeof(MultibootModule_t) );
		kModule = (KernelModule_t *)( (Address)mbModule );
	}

	return &args;
}
